<template>
	<div class="pt-4 px-[25px] md:px-[35px] pb-10">
		<template v-if="walletStore.loading.cryptoWithdrawChannel">
			<BaseLoadingCircle class="mt-20 mb-[314px] mx-auto" />
		</template>
		<template v-else-if="!walletStore.cryptoWithdrawChannel?.length">
			<BaseEmpty class="my-20" />
		</template>
		<form v-else @submit.prevent="onEnter">
			<input type="submit" class="hidden" />
			<WalletSelectCurrency
				ref="dropdownCurrencyRef"
				:options="walletStore.cryptoWithdrawChannel"
				v-model:currency="selectedCurrency"
				v-model:currency-item="selectedCurrencyItem"
				v-model:network="selectedNetwork"
				v-model:network-item="selectedNetworkItem" />
			<template v-if="selectedNetworkItem">
				<base-input
					v-model="formValue.address"
					:label="`${selectedCurrencyItem?.appName} - ${selectedNetworkItem?.cpnDisplay || selectedNetworkItem?.cpn} ${$t('wallet.address')}`"
					:placeholder="$t('wallet.enterAddress')"
					:errorT="formRule.address.result.textT"
					:is-danger="!formRule.address.result.valid"
					@blur="formRule.address.validator()"
					@focus="formReset('address')">
					<template #suffix>
						<base-paste class="ml-1" @paste="onPaste" />
					</template>
				</base-input>
				<base-tip
					class="-mt-3 mb-4"
					name="about"
					:textT="[
						'wallet.address.tip.withdraw',
						[selectedNetworkItem?.cpnDisplay || selectedNetworkItem.cpn]
					]" />
				<template v-if="selectedNetworkItem.memo">
					<base-input
						v-model="formValue.memo"
						:labelT="'wallet.address.memoTag'"
						:errorT="formRule.memo.result.textT"
						:is-danger="!formRule.memo.result.valid"
						@blur="formRule.memo.validator()"
						@focus="formReset('memo')">
						<template #title>
							<div class="inline-flex items-center gap-2 app-text-react" @click="showTag = true">
								<span>{{ $t('wallet.address.memoTag') }}</span>
								<BaseIcon class="text-t-2" name="about" size="16" />
							</div>
						</template>
						<template #suffix>
							<base-paste class="ml-1" @paste="onPaste" />
						</template>
					</base-input>
				</template>
				<base-input
					v-model="formValue.amount"
					type="number"
					labelT="wallet.amount"
					:placeholder="$t('wallet.enterAmount')"
					:filter="(v: string) => v.slice(0, 64)"
					:errorT="formRule.amount.result.textT"
					:is-danger="!formRule.amount.result.valid"
					@blur="formRule.amount.validator()"
					@focus="formReset('amount')">
					<template #title>
						<div class="flex items-center">
							<span>{{ $t('wallet.amount') }}</span>
							<base-amount
								class="ml-auto text-t-3 text-sm"
								:value="formValue.amount"
								:currency="selectedCurrencyItem?.currency"
								hide-currency
								reverse-fiat />
						</div>
					</template>
					<template #prefix></template>
					<template #suffix>
						<base-currency
							class="ml-1"
							:currency="
								walletStore.walletConfig.displayCryptoInFiat
									? walletStore.walletConfig.selectedFiatCurrency
									: selectedCurrency
							" />
						<div
							class="flex items-center h-10 ml-1 -mr-2 px-[10px] rounded-xl bg-bg-3 app-bg-react"
							:class="{ '!cursor-not-allowed': !selectedCurrencyItem }"
							@click="handleMax">
							{{ $t('wallet.max') }}
						</div>
					</template>
				</base-input>
				<div class="-mt-3 mb-4">
					<base-tip class="mb-1">
						<span>{{ $t('wallet.minWithdrawAmount') }}:&nbsp;</span>
						<base-amount v-if="feeItem" :value="feeItem?.minWithdraw" :currency="feeItem?.symbol" />
					</base-tip>
					<base-tip class="mb-1">
						<span>{{ $t('wallet.withdrawFeeNetwork') }}:&nbsp;</span>
						<BaseAmount
							v-if="totalFees"
							:value="totalFees.amount"
							:currency="totalFees.currency"
							:currencyTo="totalFees.currencyTo" />
					</base-tip>
				</div>
				<base-button
					class="h-12"
					type="primary"
					textT="wallet.withdraw"
					:loading="loading"
					@click="onEnter" />
			</template>
		</form>
	</div>
	<AccountOperateVerify ref="operateVerifyRef" @close="loading = false" @finish="onSubmit" />
	<BasePopupSmall v-model="showTag" class="pb-5" titleT="wallet.address.memoTag">
		<div class="h-[25px]" />
		<div class="text-t-2">{{ $t('wallet.address.memoTagDesc') }}</div>
		<div class="h-[25px]" />
		<BaseButton class="h-10" type="primary" text-t="action.confirm" @click="showTag = false" />
	</BasePopupSmall>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
import { find } from 'lodash-es'
import {
	BaseAmount,
	BaseButton,
	BaseCurrency,
	BaseDropdown,
	BaseEmpty,
	BaseIcon,
	BaseInput,
	BaseLoadingCircle,
	BasePaste,
	BasePopupSmall,
	BaseTip
} from '@/components/base'
import { AccountOperateVerify } from '@/components/account'
import { Action, NetworkAddressItem } from '@/types'
import { WalletSelectCurrency } from '@/components/wallet'
import { CurrencyEnum } from '@/enums'
import {
	calcAmount,
	calcExchangeRate,
	Decimals,
	fmtBalanceDecimal,
	isLength,
	isWalletAddress,
	showSuccess,
	t
} from '@/utils'
import { withdraw } from '@/api/wallet.ts'
import { useRequest } from '@/hooks'
import { useWalletStore } from '@/store'
import { RuleType } from '@/components/base/input-rule/index.vue'

defineOptions({ name: 'ViewsWalletWithdrawCrypto' })

const walletStore = useWalletStore()
const operateVerifyRef = ref<InstanceType<typeof AccountOperateVerify>>()
const selectedCurrency = ref<CurrencyEnum | ''>('')
const selectedCurrencyItem = ref<any>()
const selectedNetwork = ref('')
const selectedNetworkItem = ref<NetworkAddressItem>()
const dropdownCurrencyRef = ref<InstanceType<typeof BaseDropdown>>()
const showTag = ref(false)
const formValue = reactive({
	address: '',
	amount: '',
	memo: ''
})
const formRule = reactive({
	address: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.address.result = { valid: true })
			if (action === Action.input) formRule.address.hasInput = true
			if (action === Action.blur && !formRule.address.hasInput) return
			const value = formValue.address
			let msg = ''
			if (!value) {
				msg = 'tip.input.required'
			} else if (!isWalletAddress(value)) {
				msg = 'usdtAddressAdd.addressErrorText'
			} else if (walletStore.allDepositWalletAddress.includes(value)) {
				msg = 'wallet.cannotUseSelfDepositAddress'
			}
			formRule.address.result = { textT: msg, valid: !msg }
		}
	},
	memo: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.memo.result = { valid: true })
			if (action === Action.input) formRule.memo.hasInput = true
			if (action === Action.blur && !formRule.memo.hasInput) return
			const value = formValue.memo
			let msg = ''
			if (selectedNetworkItem.value?.memo) {
				if (!value) {
					msg = 'wallet.address.memoTagRequired'
				} else if (!isLength(value, 2, 32)) {
					msg = 'error.invalidFormat'
				}
			}
			formRule.memo.result = { textT: msg, valid: !msg }
		}
	},
	amount: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.amount.result = { valid: true })
			if (action === Action.input) formRule.amount.hasInput = true
			if (action === Action.blur && !formRule.amount.hasInput) return
			const value = formValue.amount
			let msg = ''
			if (selectedCurrencyItem.value && feeItem.value) {
				const { currency, freeAmount } = selectedCurrencyItem.value
				const { minWithdraw, maxWithdraw, symbol } = feeItem.value
				const _minWithdraw = calcAmount(minWithdraw, symbol, walletStore.fiatOrFalse || currency)
				const _maxWithdraw = calcAmount(maxWithdraw, symbol, walletStore.fiatOrFalse || currency)
				const maxInput = getMaxInput()
				const toOriginal = calcExchangeRate(walletStore.fiatOrFalse || currency, currency, value)
				if (!value) {
					msg = 'tip.input.required'
				} else if (
					// 输入值转原始币种 > 原始币种余额 || 输入值 > 当前余额减去手续费后的余额
					Number(toOriginal) > Number(freeAmount) ||
					Number(value) > (maxInput?.maxBalance ?? Number(value))
				) {
					msg = 'wallet.balanceInsufficient'
				} else if (Number(value) < Math.max(0, Number(_minWithdraw.amount) || NaN)) {
					msg = 'wallet.cannotMinWithdrawAmount'
				} else if (Number(value) > (Number(_maxWithdraw.amount) || NaN)) {
					msg = 'wallet.cannotMaxWithdrawAmount'
				}
			}
			formRule.amount.result = { textT: msg, valid: !msg }
		}
	}
})
const feeItem = computed(() => {
	return find(selectedCurrencyItem.value?.cryptoChannelDtos, { assetId: selectedNetwork.value })
})
const totalFees = computed(() => calcTotalFees())

const formReset = (field: keyof typeof formRule, withValue: boolean = false) => {
	if (withValue && formValue[field]) formValue[field] = ''
	nextTick(() => {
		formRule[field]?.hasInput && (formRule[field].hasInput = false)
		formRule[field]?.validator?.(Action.reset)
	})
}
// 计算总手续费 => 固定费用
const calcTotalFees = () => {
	if (!selectedCurrencyItem.value || !feeItem.value) return
	const { currency } = selectedCurrencyItem.value
	const { userFee } = feeItem.value
	// const feeAmount = Decimals.mul(amount, Decimals.div(userFee, 100))
	return {
		amount: userFee,
		currency: walletStore.fiatOrFalse || currency,
		currencyTo: currency
	}
}
// 设置最大提款金额 => 当前余额 - ((提款金额 * 手续费比例) + 固定费用) 与 最大提款金额取较小值 并且大于0; 如果接口max为0则不限制
const getMaxInput = () => {
	if (!selectedCurrencyItem.value || !feeItem.value) return
	const { currency, freeAmount } = selectedCurrencyItem.value
	const { maxWithdraw, symbol } = feeItem.value
	const balance = calcAmount(freeAmount, currency)
	const _maxWithdraw = calcAmount(maxWithdraw, symbol, currency)
	const maxBalance = Decimals.sub(balance.amount, calcTotalFees()?.amount)
	const echo = Math.max(0, Math.min(Number(_maxWithdraw.amount) || Infinity, maxBalance))
	return { amount: echo, currencyTo: balance.currencyTo, maxBalance }
}

const onPaste = (text: string) => (formValue.address = text)
// 设置最大提款金额 => 当前余额 - ((提款金额 * 手续费比例) + 固定费用) 与 最大提款金额取较小值 并且大于0
const handleMax = () => {
	const maxInput = getMaxInput()
	// 根据货币类型 截断取2位或8位小数
	if (maxInput) formValue.amount = fmtBalanceDecimal(maxInput?.amount, maxInput.currencyTo)
}

const { run, loading } = useRequest(withdraw, {
	showError: true,
	onSuccess: () => {
		// walletStore.setWithdrawData({ type: 'type', id: 'type', resultId: 2, success: true })
		// walletStore.setWithdrawResultPopupShow(true)
		walletStore.setWalletWithdrawShow(false)
		showSuccess(t('withdraw.submit.success'))
	}
})
const submitDisabled = computed(() => {
	return (
		!formValue.address ||
		!formValue.amount ||
		(selectedNetworkItem.value?.memo ? !formValue.memo : false) ||
		Object.values(formRule).some(({ result: { valid } }) => !valid)
	)
})
const onEnter = async () => {
	if (loading.value) return
	Object.values(formRule).forEach(({ validator }) => validator(Action.submit))
	await nextTick(async () => {
		if (submitDisabled.value) return
		loading.value = true
		await operateVerifyRef.value?.openVerify()
	})
}
const onSubmit = (verify: any) => {
	// 几个输入框的错误提示
	// 不允许输入自己的存款地址
	// 开启法币的时候提交给接口的需要换算为原币种的金额值
	if (selectedCurrencyItem.value) {
		const { currency } = selectedCurrencyItem.value
		const toOriginal = calcExchangeRate(
			walletStore.fiatOrFalse || currency,
			currency,
			formValue.amount
		)
		run({
			address: formValue.address,
			memo: formValue.memo,
			amount: toOriginal,
			cpn: selectedNetworkItem.value?.cpn,
			currency: selectedCurrency.value,
			thirdAssetId: selectedNetworkItem.value?.thirdAssetId,
			verifyType: verify?.verifyType,
			verifyCode: verify?.verifyCode
		})
	}
}

watch(selectedCurrency, () => {
	Object.values(formRule).forEach(({ validator }) => validator(Action.reset))
})

onMounted(() => {
	walletStore.getCryptoWithdrawChannel()
})
</script>

<style scoped></style>
